package domain;

import java.util.Calendar;
import java.util.GregorianCalendar;
import javax.swing.DefaultListModel;
import javax.swing.ListModel;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Style;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;

/**
 * Met de klasse IRC wordt de chat zelf voorgesteld.
 * De klasse is de superklasse van de klasse IRCChannel waardoor de variabelen en methoden protected moeten zijn.
 * Het bevat methoden die zaken toevoegt aan het StyledDocument, methodes voor de DefaultListModel en twee get-methoden voor de gui:
 * 1 voor het StyledDocument en 1 voor de DefaultListModel.
 * @author David Covemaeker, Maarten Minnebo, Tim Van Thuyne, Toon Kint
 */

public class IRC
{
	protected Style style;
	protected StyledDocument styledDocument;
	protected DefaultListModel listModel;
	
	/**
	 * De constructor maakt het StyledDocument en de DefaultListModel aan.
	 * @param login De naam van degene die ingelogd is
	 */
	protected IRC (String login)
	{
		StyleContext styleContext = new StyleContext();
		style = styleContext.getStyle(StyleContext.DEFAULT_STYLE);
		styledDocument = new DefaultStyledDocument(styleContext);
		
		listModel = new DefaultListModel();
		listModel.addElement(login);
	}
	
	/**
	 * Geeft de tijd weer van wanneer het bericht geschreven is.
	 * Ervoor zorgen dat berichten steeds op dezelfde hoogte beginnen door een 0 te plaatsen als het uur tussen 1 en 9uur ligt.
	 * Voorbeeld van de vorm: 10u45m55s wordt 10:45:50
	 * @return "(uu:mm:ss) "
	 */
	protected String giveTime()
	{
		Calendar calendar = new GregorianCalendar();
		
		int h = Calendar.HOUR_OF_DAY;
		int m = Calendar.MINUTE;
		int s = Calendar.SECOND;
		
		String hours = (calendar.get(h) > 9) ? "" + (calendar.get(h)) : "0" + calendar.get(h);
		String minutes = (calendar.get(m) > 9) ? "" + (calendar.get(m)) : "0" + calendar.get(m);
		String seconds = (calendar.get(s) > 9) ? "" + (calendar.get(s)) : "0" + calendar.get(s);

		return "(" + hours + ":" + minutes + ":" + seconds + ")" + " ";
	}
	
	/**
	 * De message in de juiste vorm aan het StyledDocument toevoegen.
	 * Voorbeeld:
	 * (09:15:50) JAVA1: Ik ga verder werken...
	 * @param login De naam van degene die ingelogd is
	 * @param message Het bericht dat geschreven is
	 */
	protected void addChatMessage(String login, String message)
	{
		try
		{
			styledDocument.insertString(styledDocument.getLength(), giveTime() + login + ": " + message + "\n", style);
		}
		catch(BadLocationException e)
		{
			e.printStackTrace();
		}	
	}
	
	/**
	 * Zorgt ervoor dat een boodschap wordt toegevoegd aan het StyledDocument als iemand uit het kanaal de chat verlaten heeft.
	 * Daarbij controleren op de 3 mogelijke gebruikers:
	 * de gewone gebruiker, voiced of operator
	 * --> Na een QUIT message...
	 * @param login De naam van degene die ingelogd is
	 * @param reason De reden van het verlaten van de chat
	 */
	protected void addClientQuitServerMessage(String login, String reason)
	{
		if (listModel.contains(login) || listModel.contains("@" + login) || listModel.contains("+" + login))
		{
			try
			{
				styledDocument.insertString(styledDocument.getLength(), giveTime() + login + " heeft de chatserver verlaten: " + reason +
						"\n", style);
			}
			catch (BadLocationException e)
			{
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * Zorgt ervoor dat een boodschap wordt toegevoegd aan het StyledDocument als iemand uit het kanaal zijn loginnaam veranderd heeft.
	 * @param oldName De oude loginnaam
	 * @param newName De nieuwe loginnaam
	 */
	protected void addNickChangeMessage(String oldName, String newName) 
	{
		if (listModel.contains(oldName) || listModel.contains("@" + oldName) || listModel.contains("+" + oldName)) 
		{
			try 
			{
				styledDocument.insertString(styledDocument.getLength(), giveTime() + " " + oldName + " heeft zijn nickname veranderd naar " 
						+ newName + ".\n" , style);
			} 
			catch (BadLocationException e) 
			{
				e.printStackTrace();
			}	
		}
	}
	
	/**
	 * In de DefaultListModel met de users de loginnaam van de bepaalde user veranderen.
	 * Controleren op de drie naam varianten:
	 * De gewone user, voiced of operator.
	 * @param oldName De oude loginnaam
	 * @param newName De nieuwe loginnaam
	 */
	protected void changeLoginName(String oldName, String newName)
	{
		if (listModel.contains(oldName))
		{
			listModel.set(listModel.indexOf(oldName), newName);
		}
			
		if (listModel.contains("@" + oldName))
		{
			listModel.set(listModel.indexOf(oldName), "@" + newName);
		}
			
		if (listModel.contains("+" + oldName))
		{
			listModel.set(listModel.indexOf(oldName), "+" + newName);
		}		
	}
	
	/**
	 * @return Geef de DefaultListModel terug
	 */
	public ListModel getListModel()
	{
		return listModel;
	}
	
	/**
	 * @return Geeft de StyledDocument terug
	 */
	public StyledDocument getStyledDocument()
	{
		return styledDocument;
	}
}
